package com.tuuzed.android.adapter;

import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;

import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private final List<Object> mItems;
    private final Map<Class<?>, ItemViewBinder> mItemViewBinderPool;

    public RecyclerViewAdapter() {
        this(16);
    }

    public RecyclerViewAdapter(int typeCount) {
        this(new LinkedList<>(), typeCount);
    }

    public RecyclerViewAdapter(@NonNull List<Object> items, int typeCount) {
        this.mItems = items;
        this.mItemViewBinderPool = new HashMap<>(typeCount);
    }

    public List<Object> getItems() {
        return mItems;
    }

    public RecyclerViewAdapter addItem(@NonNull Object item) {
        mItems.add(item);
        return this;
    }

    public RecyclerViewAdapter addItems(@NonNull Collection<?> items) {
        mItems.addAll(items);
        return this;
    }

    public RecyclerViewAdapter clearItems() {
        mItems.clear();
        return this;
    }

    public <T, VH extends RecyclerView.ViewHolder> RecyclerViewAdapter register(@NonNull Class<T> itemType,
                                                                                @NonNull ItemViewBinder<T, VH> itemViewBinder) {
        mItemViewBinderPool.put(itemType, itemViewBinder);
        return this;
    }

    public RecyclerViewAdapter attach(@NonNull RecyclerView recyclerView) {
        recyclerView.setAdapter(this);
        return this;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        ItemViewBinder itemViewBinder = getItemViewBinder(viewType);
        return itemViewBinder.onCreateViewHolder(parent, viewType);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        ItemViewBinder itemViewBinder = getItemViewBinder(position);
        Object item = mItems.get(position);
        if (item != null) {
            //noinspection unchecked
            itemViewBinder.onBindViewHolder(holder, item, position);
        }
    }

    @Override
    public int getItemCount() {
        return mItems.size();
    }

    @Override
    public int getItemViewType(int position) {
        return position;
    }

    @NonNull
    private ItemViewBinder getItemViewBinder(int position) {
        Class<?> clazz = mItems.get(position).getClass();
        ItemViewBinder itemViewBinder = mItemViewBinderPool.get(clazz);
        if (itemViewBinder == null) {
            throw new NullPointerException(clazz.getName() + " unregistered");
        }
        return itemViewBinder;
    }

}
